package com.eshopping.midleware.impldao;

import java.io.Serializable;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.stereotype.Component;
import com.eshopping.midleware.idao.Dao;

@Component
public class DaoImpl implements Dao {

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    public <T> void save(final T o) {
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            session.save(o);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
      }

    public void delete(final Object object) {
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            session.delete(object);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }

    public <T>void update(final T o) {
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            session.update(o);
            session.getTransaction().commit();
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }
    
    @SuppressWarnings({"unused", "unchecked"})
    public <T>T get(final Class<T> type, final Object o) {
        T result = null ;
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            result= (T) session.get(type, (Serializable) o);
        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
        return result;
    }

    @SuppressWarnings({"unchecked", "unused"})
    public <T>T get(String table,String attribute, String chaine) {
        T result = null ;
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            Query query = session.createQuery("from " +table+ " where " + attribute + "= :valeur");
            query.setParameter("valeur", chaine);
            result= (T) query.list().get(0);
        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
        return result;
    }

    @SuppressWarnings({"unchecked", "unused"})
    public <T>List<T> getAll(final Class<T> type) {
        List<T> result = null;
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            final Criteria crit = session.createCriteria(type);
            result=crit.list();
        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
        return result;

    }
    
    public <T>void saveOrUpdate(final T o) {
        Transaction trns = null;
        Session session = sessionFactory.openSession();
         try {
             trns = session.beginTransaction();
             session.saveOrUpdate(o);
             session.getTransaction().commit();
         } catch (RuntimeException e) {
             if (trns != null) {
                 trns.rollback();
             }
             e.printStackTrace();
         } finally {
             session.flush();
             session.close();
         }
    }
    
    public <T>void merge(final T o) {
        Transaction trns = null;
        Session session = sessionFactory.openSession();
        try {
            trns = session.beginTransaction();
            session.merge(o);
        } catch (RuntimeException e) {
            if (trns != null) {
                trns.rollback();
            }
            e.printStackTrace();
        } finally {
            session.flush();
            session.close();
        }
    }

}
